package com.example.juccode.juc02completableFuture.demo;

import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;

/**
 * @author: zhongkui 1365693530@qq.com
 * @Date: 2025/2/9
 */
public class FutureApiDemo {
    /**
     * ● 对于简单的业务场景使用Future完全ok
     * ● 回调通知：
     *   ○ 应对Future的完成时间，完成了可以告诉我，也就是我们的回调通知
     *   ○ 通过轮询的方式去判断任务是否完成这样非常占cpu并且代码也不优雅
     * ● 创建异步任务：Future+线程池组合
     * ● 多个任务前后依赖可以组合处理（水煮鱼--->买鱼--->调料--->下锅）：
     *   ○ 想将多个异步任务的结果组合起来，后一个异步任务的计算结果需要钱一个异步任务的值
     *   ○ 想将两个或多个异步计算合并成为一个异步计算，这几个异步计算互相独立，同时后面这个又依赖前一个处理的结果
     * ● 对计算速度选最快的：
     *   ○ 当Future集合中某个任务最快结束时，返回结果，返回第一名处理结果
     * ● 结论：
     *   ○ 使用Future之前提供的那点API就囊中羞涩，处理起来不够优雅，这时候还是让CompletableFuture以声明式的方式优雅的处理这些需求。
     *   ○ 从i到i++
     *   ○ Future能干的，CompletableFuture都能干
     */
    public static void main(String[] args) throws Exception {
        FutureTask<String> futureTask = new FutureTask<>(() -> {
            try {
                System.out.println(Thread.currentThread().getName() + "------开始执行");
                TimeUnit.MILLISECONDS.sleep(1000);} catch (Exception e) {e.printStackTrace();}
            return "task1 over";
        });
        Thread thread = new Thread(futureTask, "t1");
        thread.start();
        /**
         * get方法 阻塞等待线程执行完毕，获取返回值
         */
//        System.out.println(futureTask.get());
//        System.out.println(Thread.currentThread().getName() + "------执行完毕");
        System.out.println(Thread.currentThread().getName() + "--------处理其他任务");
        while (true){
            /**
             * isDone() 判断任务是否执行完毕
             * 轮询的方式会耗费无谓的cpu资源，而且也不见得能及时得到计算结果，如果想要异步获取结果，通常会以轮询的方式去获取结果，尽量不要阻塞。
             * 结论：Future对于结果的获取不是很友好，只能通过阻塞或轮询的方式得到任务的结果。
             */
            if (futureTask.isDone()){
                System.out.println(futureTask.get());
                break;
            }else {
                try {TimeUnit.MILLISECONDS.sleep(200);} catch (Exception e) {e.printStackTrace();}
                System.out.println("正在处理中....");
            }
        }
        System.out.println(Thread.currentThread().getName() + "------执行完毕");

    }
}
